#include <fstream>
#include <vector>
#include <iostream>
#include <memory>
#include <algorithm>
#include "adapt_prec_arith.h"

struct point
{
	double x;
	double y;

	point(double x_, double y_)
	{
		x = x_;
		y = y_;
	}

	bool operator==(point const& arg) const
	{
		if (x == arg.x && y == arg.y)
		{
			return true;
		}
		return false;
	}

	bool operator<(point const& arg) const
	{
		if (x != arg.x)
		{
			return x < arg.x;
		}
		return y < arg.y;
	}
};

point a(0.0, 0.0);

int left_turn(double a_x, double a_y, double b_x, double b_y, double c_x, double c_y)
{
	double e = 4 * std::numeric_limits<double>::epsilon();
	e *= std::abs((b_x - a_x) * (c_y - a_y)) + std::abs((b_y - a_y) * (c_x - a_x));
	double result = (b_x - a_x) * (c_y - a_y) - (b_y - a_y) * (c_x - a_x);
	if (std::abs(result) > e)
	{
		if (result > 0)
		{
			return 1;
		}
		if (result < 0)
		{
			return -1;
		}
	}
	return left_turn_apa(a_x, a_y, b_x, b_y, c_x, c_y);
}

bool left_turn_comparator(point const& b, point const& c)
{
	int turn = left_turn(a.x, a.y, b.x, b.y, c.x, c.y);
	if (turn == 1)
	{
		return true;
	}
	if (turn == 0)
	{
		return (b < c);
	}
	return false;
}

int main()
{
	//std::ifstream in("in.txt");
	//std::ofstream out("out.txt");
	int n;
	std::istream & in = std::cin;
	std::ostream & out = std::cout;
	in >> n;

	std::vector<point> points;

	for (int i = 0; i < n; i++)
	{
		double x, y;
		in >> x >> y;
		points.push_back(point(x, y));
	}

	if (n < 3)
	{
		out << n << '\n';
		out.precision(30);
		for (auto i = points.begin(); i < points.end(); i++)
		{
			out << (*i).x << " " << (*i).y << '\n';
		}
		return 0;
	}

	std::swap(*std::min_element(points.begin(), points.end()), points[0]);
	a = points[0];
	std::sort(points.begin() + 1, points.end(), left_turn_comparator);
	
	std::vector<point> stack;
	stack.push_back(points[0]);
	stack.push_back(points[1]);

	for (auto i = points.begin() + 2; i < points.end(); i++)
	{
		int s = stack.size();
		int turn = left_turn(stack[s - 2].x, stack[s - 2].y, stack[s - 1].x, stack[s - 1].y, (*i).x, (*i).y);
		if (turn == 1)
		{
			stack.push_back((*i));
		}
		else
		{
			while (stack.size() > 2 && turn != 1)
			{
				stack.pop_back();
				s = stack.size();
				turn = left_turn(stack[s - 2].x, stack[s - 2].y, stack[s - 1].x, stack[s - 1].y, (*i).x, (*i).y);
			}
			if (turn != 1)
			{
				stack.pop_back();
			}
			stack.push_back((*i));
		}
	}

	if (stack[0] == stack[1])
	{
		stack.pop_back();
	}

	out << stack.size() << '\n';
	out.precision(30);
	for (auto i = stack.begin(); i < stack.end(); i++)
	{
		out << (*i).x << " " << (*i).y << '\n';
	}
	return 0;
}